import ParticleSystem from "../js/particle-system.esm.js"

export default class Wind3D {
  constructor(panel, data) {
    this.viewer = new Cesium.Viewer('cesiumContainer', {
      baseLayerPicker: false,
      geocoder: false,
      infoBox: false,
      fullscreenElement: 'cesiumContainer',
      scene3DOnly: true,
      timeline: false,
      animation: false,
      fullscreenButton: false,
      homeButton: false,
      navigationHelpButton: false,
      imageryProvider: new Cesium.BingMapsImageryProvider({
        url: "https://dev.virtualearth.net",
        key: "AtkX3zhnRe5fyGuLU30uZw8r3sxdBDnpQly7KfFTCB2rGlDgXBG3yr-qEiQEicEc",
        mapStyle: Cesium.BingMapsStyle.AERIAL
      })
    })
    this.scene = this.viewer.scene
    this.camera = this.viewer.camera

    this.panel = panel;

    this.viewerParameters = {
      lonRange: new Cesium.Cartesian2(),
      latRange: new Cesium.Cartesian2(),
      pixelSize: 0.0
    }

    /* 设置初始视角 */
    this.viewer.scene.camera.setView({
      destination: new Cesium.Cartesian3(-2475064.4457, 5614495.12, 2511055.56),
      orientation: {
        heading: 6.144,
        pitch: -1.567, // 初始倾角不能过大，最好垂直的
        roll: 0
      }
    })

    // use a smaller earth radius to make sure distance to camera > 0
    this.globeBoundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.ZERO, 0.99 * 6378137.0);
    this.updateViewerParameters();

    const userInputParams = this.panel.getUserInput()
    this.particleSystem = new ParticleSystem(
      this.scene.context,
      data,
      userInputParams,
      this.viewerParameters
    );
    this.addPrimitives();
    this.setupEventListeners();

    this.imageryLayers = this.viewer.imageryLayers;
  }

  addPrimitives() {
    // the order of primitives.add() should respect the dependency of primitives
    this.scene.primitives.add(this.particleSystem.particlesComputing.primitives.calculateSpeed);
    this.scene.primitives.add(this.particleSystem.particlesComputing.primitives.updatePosition);
    this.scene.primitives.add(this.particleSystem.particlesComputing.primitives.postProcessingPosition);

    this.scene.primitives.add(this.particleSystem.particlesRendering.primitives.segments);
    this.scene.primitives.add(this.particleSystem.particlesRendering.primitives.trails);
    this.scene.primitives.add(this.particleSystem.particlesRendering.primitives.screen);
  }

  updateViewerParameters() {
    this.viewerParameters.lonRange.x = 114.2641848923519916;// lonLatRange.lon.min;
    this.viewerParameters.lonRange.y = 113.3245601336276565;//lonLatRange.lon.max;
    this.viewerParameters.latRange.x = 22.0021053095437118;// lonLatRange.lat.min;
    this.viewerParameters.latRange.y = 22.8137807481400863;//lonLatRange.lat.max;

    var pixelSize = this.camera.getPixelSize(
      this.globeBoundingSphere,
      this.scene.drawingBufferWidth,
      this.scene.drawingBufferHeight
    );

    if (pixelSize > 0) {
      this.viewerParameters.pixelSize = pixelSize;
    }
  }

  setupEventListeners() {
    const that = this;

    this.camera.moveStart.addEventListener(function () {
      that.scene.primitives.show = false;
    });

    this.camera.moveEnd.addEventListener(function () {
      that.updateViewerParameters();
      that.particleSystem.applyViewerParameters(that.viewerParameters);
      that.scene.primitives.show = true;
    });

    var resized = false;
    window.addEventListener("resize", function () {
      resized = true;
      that.scene.primitives.show = false;
      that.scene.primitives.removeAll();
    });

    this.scene.preRender.addEventListener(function () {
      if (resized) {
        that.particleSystem.canvasResize(that.scene.context);
        resized = false;
        that.addPrimitives();
        that.scene.primitives.show = true;
      }
    });

    window.addEventListener('particleSystemOptionsChanged', function () {
      that.particleSystem.applyUserInput(that.panel.getUserInput());
    });
  }

  debug() {
    const that = this;

    var animate = function () {
      that.viewer.resize();
      that.viewer.render();
      requestAnimationFrame(animate);
    }
    animate();
  }
}
